Consider all targets for platform requirements
authorAlex Crichton <alex@alexcrichton.com>
Thu, 29 Jan 2015 06:28:31 +0000 (22:28 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Thu, 29 Jan 2015 19:20:11 +0000 (11:20 -0800)
Previously a build script would assign itself to the platform requirement for
the first target of a package, but it's more correct to consider all targets for
platform requirements as there may be both a plugin and target requirement.

Closes #1230

src/cargo/ops/cargo_rustc/context.rs
src/cargo/ops/cargo_rustc/mod.rs
tests/test_cargo_compile_plugins.rs
tests/test_cargo_cross_compile.rs

index 81573d8b4d9f4af33bec2ccfd41ffb95e9b2dfaa..7e4f79cba8f5894784c4418f6ada73b276b137e0 100644 (file)
@@ -360,7 +360,7 @@ impl<'a, 'b: 'a> Context<'a, 'b> {
 }
 
 impl Platform {
-    fn combine(self, other: Platform) -> Platform {
+    pub fn combine(self, other: Platform) -> Platform {
         match (self, other) {
             (Platform::Target, Platform::Target) => Platform::Target,
             (Platform::Plugin, Platform::Plugin) => Platform::Plugin,
index 20e72393a96ae29a81fe43d42f1c2880319d5e58..90f48e230e7e96b15b81e2b4d6d148c98a26c993 100644 (file)
@@ -284,10 +284,13 @@ fn compile<'a, 'b>(targets: &[&'a Target], pkg: &'a Package,
         // it once per context.
         if !target.get_profile().is_custom_build() { continue }
         let mut reqs = Vec::new();
-        let requirement = targets.iter().find(|t| {
-            !t.get_profile().is_custom_build() && !t.get_profile().is_doc()
-        }).map(|&other_target| {
-            cx.get_requirement(pkg, other_target)
+        let requirement = targets.iter().fold(None::<Platform>, |req, t| {
+            if !t.get_profile().is_custom_build() && !t.get_profile().is_doc() {
+                let r2 = cx.get_requirement(pkg, *t);
+                req.map(|r| r.combine(r2)).or(Some(r2))
+            } else {
+                req
+            }
         }).unwrap_or(Platform::Target);
         match requirement {
             Platform::Target => reqs.push(Platform::Target),
@@ -369,6 +372,7 @@ fn rustc(package: &Package, target: &Target,
 
         Ok((Work::new(move |desc_tx| {
             let mut rustc = rustc;
+            debug!("about to run: {}", rustc);
 
             // Only at runtime have we discovered what the extra -L and -l
             // arguments are for native libraries, so we process those here. We
@@ -412,6 +416,7 @@ fn rustc(package: &Package, target: &Target,
                        pass_l_flag: bool,
                        current_id: &PackageId) -> CommandPrototype {
         for id in native_lib_deps.into_iter() {
+            debug!("looking up {} {:?}", id, kind);
             let output = &build_state[(id.clone(), kind)];
             for path in output.library_paths.iter() {
                 rustc = rustc.arg("-L").arg(path);
index d20714cb725bbdec47ef6448af8c88d0ef8cf540..f2a5d7af19775269d715b49c4b8f8d8f800664c3 100644 (file)
@@ -165,3 +165,25 @@ test!(plugin_with_dynamic_native_dependency {
     assert_that(foo.cargo_process("build").env("SRC", Some(lib.as_vec())),
                 execs().with_status(0));
 });
+
+test!(plugin_integration {
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "foo"
+            version = "0.0.1"
+            authors = []
+            build = "build.rs"
+
+            [lib]
+            name = "foo"
+            plugin = true
+            doctest = false
+        "#)
+        .file("build.rs", "fn main() {}")
+        .file("src/lib.rs", "")
+        .file("tests/it_works.rs", "");
+
+    assert_that(p.cargo_process("test"),
+                execs().with_status(0));
+});
index a4d2ed024e7c9640572d8ce62f2604327bd19f6a..968ff1acaec1458656856b28d3f07524548224fd 100644 (file)
@@ -652,3 +652,30 @@ test!(build_script_only_host {
     assert_that(p.cargo_process("build").arg("--target").arg(&target).arg("-v"),
                 execs().with_status(0));
 });
+
+test!(plugin_build_script_right_arch {
+    if disabled() { return }
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "foo"
+            version = "0.0.1"
+            authors = []
+            build = "build.rs"
+
+            [lib]
+            name = "foo"
+            plugin = true
+        "#)
+        .file("build.rs", "fn main() {}")
+        .file("src/lib.rs", "");
+
+    assert_that(p.cargo_process("build").arg("-v").arg("--target").arg(alternate()),
+                execs().with_status(0)
+                       .with_stdout(format!("\
+{compiling} foo v0.0.1 ([..])
+{running} `rustc build.rs [..]`
+{running} `[..]build-script-build[..]`
+{running} `rustc src[..]lib.rs [..]`
+", compiling = COMPILING, running = RUNNING)));
+});